﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using Repositories.Implementations;

namespace Repositories.Interfaces
{
    public interface IBaseRepository<T>
    {
        /// <summary>
        /// Inserts the specified entity.
        /// </summary>
        /// <param name="entity">The entity.</param>
        void Insert(T entity);

        /// <summary>
        /// Deletes the specified entity.
        /// </summary>
        /// <param name="entity">The entity.</param>
        void Delete(T entity);

        /// <summary>
        /// Updates the specified entity.
        /// </summary>
        /// <param name="entity">The entity.</param>
        void Update(T entity);

        /// <summary>
        /// Gets the query.
        /// </summary>
        /// <param name="predicate">The predicate.</param>
        /// <returns></returns>
        IQueryable<T> GetQuery(Expression<Func<T, bool>> predicate);

        /// <summary>
        /// Gets the query.
        /// </summary>
        /// <returns></returns>
        IQueryable<T> GetQuery();

        /// <summary>
        /// Attaches to.
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <remarks></remarks>
        void AttachTo(T entity);

        /// <summary>
        /// Deattaches to.
        /// </summary>
        /// <param name="combo">The entity.</param>
        /// <remarks></remarks>
        void DeattachTo(T combo);


        IQueryable<T> GetQuery(Expression<Func<T, object>> sortParam, bool asc, out long rowsCount);
        /// <summary>
        /// Gets the query.
        /// </summary>
        /// <param name="sortParam">The predicate.</param>
        /// <param name="page">The page.</param>
        /// <param name="pageSize">Size of the page.</param>
        /// <param name="asc">if set to <c>true</c> [asc].</param>
        /// <param name="rowsCount">The rows count.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        IQueryable<T> GetQuery(Expression<Func<T, object>> sortParam, int page, int pageSize, bool asc, out long rowsCount);

        /// <summary>
        /// Gets the query sort have predicate and paging.
        /// </summary>
        /// <param name="predicate">The predicate.</param>
        /// <param name="sortParam">The sort param.</param>
        /// <param name="page">The page.</param>
        /// <param name="pageSize">Size of the page.</param>
        /// <param name="asc">if set to <c>true</c> [asc].</param>
        /// <param name="rowsCount">The rows count.</param>
        /// <returns></returns>
        IQueryable<T> GetQuery(Expression<Func<T, bool>> predicate, Expression<Func<T, object>> sortParam, int page, int pageSize, bool asc, out long rowsCount);

        /// <summary>
        ///  Gets the query sort have predicate.
        /// </summary>
        /// <param name="predicate">The predicate.</param>
        /// <param name="sortParam">The sort param.</param>
        /// <param name="asc">if set to <c>true</c> [asc].</param>
        /// <param name="rowsCount">The rows count.</param>
        /// <returns></returns>
        IQueryable<T> GetQuery(Expression<Func<T, bool>> predicate, Expression<Func<T, object>> sortParam, bool asc,
                                      out long rowsCount);
        /// <summary>
        /// Gets the unit of work.
        /// </summary>
        /// <value>The unit of work.</value>
        /// <remarks></remarks>
        UnitOfWork UnitOfWork
        {
            get;
        }
    }
}
